import { Directive, DirectiveBinding } from 'vue';
/* 在 n 秒内函数只能执行一次 */

function debounce(func: Function, wait: number) {
  let timeout: ReturnType<typeof setTimeout> | null = null;

  return function (this: any, ...args: any[]) {
    if (timeout) clearTimeout(timeout);

    timeout = setTimeout(() => {
      func.apply(this, args);
    }, wait);
  };
}


interface ElType extends HTMLElement {
  __debounceHandler__: () => void;
}

const debounceDirective: Directive = {
  mounted(el: ElType, binding: DirectiveBinding) {
    if (typeof binding.value !== 'function') {
      console.warn('v-debounce expects a function as the value');
      return;
    }

    // 使用指令参数设置防抖时间，如果没有设置则使用默认值 500ms
    const wait = binding.arg ? parseInt(binding.arg) : 500;

    el.__debounceHandler__ = debounce(binding.value, wait);
    el.addEventListener('click', el.__debounceHandler__);
  },
  beforeUnmount(el: ElType) {
    el.removeEventListener('click', el.__debounceHandler__);
  },
};

export default debounceDirective;
